﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Newtonsoft.Json;

namespace BO
{
    [Serializable]
    public class MyData
    {

        public string SqlTxt { get; set; }
        public KeyValuePair<string, object>[] SqlParas { get; set; }

        public MyData(DbCommand cmd)
        {
            cmd.CommandTimeout = 0;
            SqlTxt = cmd.CommandText;
            SqlParas = new KeyValuePair<string, object>[cmd.Parameters.Count];
            for (int i = 0; i < cmd.Parameters.Count; i++)
            {
                SqlParas[i] = new KeyValuePair<string, object>(cmd.Parameters[i].ParameterName, cmd.Parameters[i].Value);
            }

        }
    }

    public class DataServeice
    {
        public static string serverAddr =
            ConfigurationManager.AppSettings["DataServer"];

        const string DirectSQL = "DirectSQL";
        const string ViaPHP = "ViaPHP";
        public static string ServiceType = ViaPHP;

        public static IList<IDictionary<string, object>> FecthData(DbCommand cm)
        {
            switch (ServiceType)
            {
                case ViaPHP:
                    var reqObj = new MyData(cm);

                    string s = ComminacateToServer("FecthData.php", reqObj);
                    if (s.StartsWith("\"Failed:"))
                    {
                        throw new Exception(s);
                    }
                    return JsonConvert.DeserializeObject<IList<IDictionary<string, object>>>(s);
                case DirectSQL:
                    using (var cn = DbFactory.GetConnection(GlobalVar.ConnectionString))
                    {
                        cn.Open();
                        cm.Connection = cn;
                        var dr = cm.ExecuteReader();

                        var ret = new List<IDictionary<string, object>>();
                        while (dr.Read())
                        {
                            var obj = new Dictionary<string, object>();
                            for (int i = 0; i < dr.FieldCount; i++)
                            {
                                obj.Add(dr.GetName(i), dr.GetValue(i));
                            }
                            ret.Add(obj);
                        }
                        cn.Dispose();
                        return ret;
                    }

                    break;
            }
            return null;
        }

        internal static void BatchUpdateData(List<DbCommand> cmdList)
        {

            if (cmdList == null || cmdList.Count == 0)
                return;
            switch (ServiceType)
            {
                case ViaPHP:
                    var reqObj = new List<MyData>();
                    foreach (var cm in cmdList)
                    {
                        reqObj.Add(new MyData(cm));
                    }
                    string s = ComminacateToServer("BatchUpdateData.php", reqObj);
                    return;
                case DirectSQL:
                    var cn = DbFactory.GetConnection(GlobalVar.ConnectionString);
                    cn.Open();
                    var tr = cn.BeginTransaction(DbFactory.IsolationLevel);
                    try
                    {
                        foreach (var cm in cmdList)
                        {
                            cm.Connection = cn;
                            cm.Transaction = tr;
                            cm.ExecuteNonQuery();
                        }
                        tr.Commit();
                    }
                    catch (Exception exp)
                    {
                        tr.Rollback();
                    }
                    finally
                    {
                        tr.Dispose();
                        cn.Dispose();
                    }
                    return;
            }
        }

        private static string ComminacateToServer(string file, object pdata)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(serverAddr + file);
            req.Method = "POST";

            var reqStream = req.GetRequestStream();

            var reqStr = JsonConvert.SerializeObject(pdata);
            var en = new UTF8Encoding();
            var data = en.GetBytes(reqStr);
            //var data = Encoding.GetEncoding("utf8").GetBytes(reqStr);
            reqStream.Write(data, 0, data.Length);
            HttpWebResponse rsp = (HttpWebResponse)req.GetResponse();

            var rdr = new StreamReader(rsp.GetResponseStream(), Encoding.GetEncoding("utf-8"));
            string s = rdr.ReadToEnd();
            return s;
        }
    }
}
